package cn.com.libertymutual.sp.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sp.bean.SysOperationLog;
import cn.com.libertymutual.sp.bean.TbSpSaleLog;
import cn.com.libertymutual.sp.dao.OperationLogDao;
import cn.com.libertymutual.sp.dao.SpSaleLogDao;
import cn.com.libertymutual.sp.service.api.OperationLogService;

@Service("operationLogService")
public class OperationLogServiceImpl implements OperationLogService {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private OperationLogDao operationLogDao;

	@Autowired
	private SpSaleLogDao spSaleLogDao;

	// 新开事务，保障该方法持久化成功，不受其他事务回滚
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	@Override
	public boolean saveLog(TbSpSaleLog saleLog, SysOperationLog operationLog) {
		if (saleLog != null) {
			spSaleLogDao.save(saleLog);
		}
		if (operationLog != null) {
			operationLogDao.save(operationLog);
		}
		return true;
	}

	@Override
	public ServiceResult logList(int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.DESC, "operationTime");
		Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
		sr.setResult(operationLogDao.findAll(pageable));
		return sr;
	}

	@Override
	public ServiceResult queryLog(String userId, String level, String startTime, String endTime, int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.DESC, "id");
		Page<SysOperationLog> page = operationLogDao.findAll(new Specification<SysOperationLog>() {
			public Predicate toPredicate(Root<SysOperationLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicate = new ArrayList<Predicate>();

				if (StringUtils.isNotEmpty(level) && !"-1".equals(level)) {

					predicate.add(cb.equal(root.get("level").as(String.class), level));
				}
				if (StringUtils.isNotEmpty(userId)) {
					log.info(userId);
					predicate.add(cb.like(root.get("userId").as(String.class), userId));
				}

				if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
					predicate.add(cb.greaterThanOrEqualTo(root.get("operationTime").as(String.class), startTime));
					predicate.add(cb.lessThanOrEqualTo(root.get("operationTime").as(String.class), endTime));
				}

				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		}, PageRequest.of(pageNumber - 1, pageSize, sort));

		sr.setResult(page);
		return sr;
	}

	@Override
	public ServiceResult querySaleLog(String requestData, String responseData, String startTime, String endTime, String userCode, String mark,
			String operation, int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.DESC, "id");
		Page<TbSpSaleLog> page = spSaleLogDao.findAll(new Specification<TbSpSaleLog>() {
			public Predicate toPredicate(Root<TbSpSaleLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicate = new ArrayList<Predicate>();

				if (StringUtils.isNotEmpty(requestData)) {

					predicate.add(cb.like(root.get("requestData").as(String.class), "%" + requestData + "%"));
				}
				if (StringUtils.isNotEmpty(responseData)) {
					log.info(responseData);
					predicate.add(cb.like(root.get("responseData").as(String.class), "%" + responseData + "%"));
				}
				if (StringUtils.isNotEmpty(mark)) {
					log.info(mark);
					predicate.add(cb.like(root.get("mark").as(String.class), "%" + mark + "%"));
				}
				if (StringUtils.isNotEmpty(operation)) {
					log.info(operation);
					predicate.add(cb.like(root.get("operation").as(String.class), "%" + operation + "%"));
				}
				if (StringUtils.isNotEmpty(userCode)) {
					log.info(userCode);
					predicate.add(cb.equal(root.get("userCode").as(String.class),  userCode));
				}

				if (StringUtils.isNotEmpty(startTime)) {
					predicate.add(cb.greaterThanOrEqualTo(root.get("requestTime").as(String.class), startTime));
				}
				if (StringUtils.isNotEmpty(endTime)) {
					predicate.add(cb.lessThanOrEqualTo(root.get("requestTime").as(String.class), endTime));
				}

				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		}, PageRequest.of(pageNumber - 1, pageSize, sort));

		sr.setResult(page);
		return sr;
	}

	@Override
	public ServiceResult deleteSaleLog(Integer id) {
		ServiceResult sr = new ServiceResult();
		spSaleLogDao.deleteById(id);
		sr.setSuccess();
		return sr;
	}

}
